package com.github.icloudpay.pay.core.service.payForAnother.helipay.service;

import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.github.icloudpay.pay.core.feign.PayChannelConfigFeign;
import com.github.icloudpay.pay.core.inter.PayForAnotherService;
import com.github.icloudpay.pay.core.util.HttpClientUtil;
import com.github.icloudpay.pay.core.util.MD5;
import com.github.icloudpay.pay.core.util.RSA;
import com.github.wxiaoqi.security.common.admin.pay.request.PayForAnotherRequest;
import com.github.wxiaoqi.security.common.admin.pay.response.PayForAnotherResponse;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.common.util.Base64Utils;
import com.github.wxiaoqi.security.common.util.RSAUtil;

/**
 * 合利宝代付
 * @author hexufeng
 *
 */
@Service("heliPayForAnotherService")
public class HeliPayForAnotherService implements PayForAnotherService{
	
	private static final Logger logger = LoggerFactory.getLogger(HeliPayForAnotherService.class);
	
	@Autowired
	private PayChannelConfigFeign payChannelConfigFeign;
	@Value("${platform.cardNoPrivateKey}")
	private String txPwdPrivateKey;
	@Value("${pay_for_another.url}")
    private String url;

	@Override
	public PayForAnotherResponse toPayForAnother(PayForAnotherRequest request) {
		
		logger.info("****************调用合利宝代付接口开始*******************");
		
		PayForAnotherResponse payForAnotherResponse = new PayForAnotherResponse();

		Map<String, Object> reqMap = new HashMap<String, Object>();
    	reqMap.put("platformId", request.getPlatformId());
    	reqMap.put("merchantId", request.getMerchantId());
    	reqMap.put("payChannelNo", request.getPayChannelNo());
		Map<String, Object> respMap = payChannelConfigFeign.query(reqMap);
        if(!(boolean) respMap.get("success")){
			payForAnotherResponse.setSuccess(false);
			payForAnotherResponse.setCode(ResponseCode.PAYCHANNEL_CONFIGURATION_NOTEXIST.getCode());
			payForAnotherResponse.setMsg(ResponseCode.PAYCHANNEL_CONFIGURATION_NOTEXIST.getMessage());
			return payForAnotherResponse;
		}
        
        @SuppressWarnings("unchecked")
		Map<String, Object> configMap = (Map<String, Object>)respMap.get("payChannelConfigInfo");
		
		Map<String,Object> sPara = new HashMap<String,Object>();
		sPara.put("P1_bizType","Transfer");
		sPara.put("P2_orderId",request.getOutOrderNo());
		sPara.put("P3_customerNumber",(String)configMap.get("outMerNo"));//商户号
		sPara.put("P4_amount",request.getAmount());
		sPara.put("P5_bankCode",request.getBankCode());
		//银行卡解密
		String bankNo = null;
		byte[] andEnData = Base64Utils.decode(request.getBankAccountNo());
    	try {
    		byte[] dedata = RSAUtil.pcDecryptByPrivateKey(txPwdPrivateKey,andEnData);
    		bankNo = new String(dedata);
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
		sPara.put("P6_bankAccountNo",bankNo);
		sPara.put("P7_bankAccountName",request.getBankAccountName());
		if(!StringUtils.isEmpty(request.getBankUnionCode())){
			sPara.put("P8_biz","B2B");
		}else{
			sPara.put("P8_biz","B2C");
		}
		sPara.put("P9_bankUnionCode",request.getBankUnionCode());
		sPara.put("P10_feeType","PAYER");//收取付款方
		sPara.put("P11_urgency","true");
		sPara.put("P12_summary","结算");
		
		//拼接签名串
		String signStr = getSignStr(sPara);
		String sign = "";
		try {
			PrivateKey key = RSA.getPrivateKey((String)configMap.get("outMerPrivateKey"));
			sign = RSA.sign(signStr, key);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		sPara.put("sign",sign);
		logger.info("代付请求报文:{}",sPara);
		StringBuffer sbHtml = new StringBuffer();
		List<String> keys = new ArrayList<String>(sPara.keySet());
		
		//post方式传递
		sbHtml.append("<form id=\"transferSingleForm\" name=\"transferSingleForm\" action=\"").append(url).append("\" method=\"post\">");
		String name ="";
		String value ="";
		for (int i = 0; i < keys.size(); i++) {
			 name=(String) keys.get(i);
			 value=(String) sPara.get(name);
			if(value!=null && !"".equals(value)){
				sbHtml.append("<input type=\"hidden\" name=\"").append(name).append("\" value=\"" + value + "\"/>");
			}
		}
        
        //submit按钮控件请不要含有name属性
        sbHtml.append("<input type=\"submit\" value=\"确认打款\"></form>");
        String respJson = "";
		try {
			respJson = HttpClientUtil.doPost(url, sbHtml.toString(), "utf-8");
			logger.info("代付请求返回报文:{}",respJson);
			JSONObject jsonObject = (JSONObject) JSONObject.parse(respJson);
			String respSign = (String) jsonObject.get("sign");
			
			//返回值验签MD5
			Map<String,Object> responseMap = new HashMap<String,Object>();
			responseMap.put("rt1_bizType", (String) jsonObject.get("rt1_bizType"));
			responseMap.put("rt2_retCode", (String) jsonObject.get("rt2_retCode"));
			responseMap.put("rt4_customerNumber", (String) jsonObject.get("rt4_customerNumber"));
			responseMap.put("rt5_orderId", (String) jsonObject.get("rt5_orderId"));
			responseMap.put("rt6_serialNumber", (String) jsonObject.get("rt6_serialNumber"));
			responseMap.put("sign", (String) jsonObject.get("sign"));
			String signMD5Str = getSignStr(sPara);
			String verifySign = MD5.sign(signMD5Str, "utf-8");
			if(!verifySign.equals(respSign)){
				logger.info("代付请求返回签名失败");
				payForAnotherResponse.setSuccess(false);
				payForAnotherResponse.setCode(ResponseCode.PAY_FOR_ANOTHER_FAIL.getCode());
				payForAnotherResponse.setMsg(ResponseCode.PAY_FOR_ANOTHER_FAIL.getMessage());
			}else{
				payForAnotherResponse.setStatus((String) jsonObject.get("rt2_retCode"));
				payForAnotherResponse.setSuccess(true);
				payForAnotherResponse.setCode(ResponseCode.OK.getCode());
				payForAnotherResponse.setMsg(ResponseCode.OK.getMessage());
			}
		} catch (Exception e) {
			e.printStackTrace();
			payForAnotherResponse.setSuccess(false);
			payForAnotherResponse.setCode(ResponseCode.PAY_FOR_ANOTHER_FAIL.getCode());
			payForAnotherResponse.setMsg(ResponseCode.PAY_FOR_ANOTHER_FAIL.getMessage());
			return payForAnotherResponse;
		}
		return payForAnotherResponse;
	}
	
	/**
	 * 拼接待签名字符串
	 * @param sPara
	 * @return
	 */
	private String getSignStr(Map<String,Object> sPara){
		StringBuffer sbHtml = new StringBuffer();
		List<String> keys = new ArrayList<String>(sPara.keySet());
		
		//post方式传递
		String name ="";
		String value ="";
		for (int i = 0; i < keys.size(); i++) {
			 name=(String) keys.get(i);
			 if(null != sPara.get(name)){
				 value=String.valueOf(sPara.get(name));
			 }
			if(value!=null && !"".equals(value)){
				sbHtml.append("&").append(value);
			}else{
				sbHtml.append("&");
			}
		}
		String paramStr = sbHtml.toString();
		return paramStr;
	}
	
}
